﻿using adb;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using System.Linq;
using Z.EntityFramework.Plus;
using Masuit.Tools.Security;
using System.Collections.Generic;
using PowerStation.RequestModel;
using Microsoft.EntityFrameworkCore;
using adb.excel;
using System.IO;
using Masuit.Tools;
using Microsoft.Net.Http.Headers;
using System;
using Chinese;
using System.Net.Http;
using NSoup.Nodes;
using NSoup;

namespace PowerStation.Controllers
{
    /// <summary>
    /// 天气预报
    /// </summary>
    public class WeatherController : BaseApi<WeatherController>
    {
        /// <summary>
        /// 计划发电管理
        /// </summary>
        /// <param name="content"></param>
        public WeatherController(IHttpContextAccessor content) : base(content)
        {
        }

        private static Dictionary<string, List<RequestWeatherModel>> lst = new Dictionary<string, List<RequestWeatherModel>>();

        /// <summary>
        /// 获取7天内的天气,前2天+5天
        /// </summary>
        /// <param name="keyId">城市ID</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultApi<List<RequestWeatherModel>>> List(decimal keyId = 450100)
        {
            try
            {
                var data = DateTime.Today;
                var key = $"{data:yyyyMMdd}{keyId:0}";
                if (lst.ContainsKey(key))
                {
                    return ResultApi.ok(lst[key]);
                }
                var keyModel = await this._db.tKey.FirstOrDefaultAsync(x => x.keyId == keyId);
                if (keyModel == null) return ResultApi.error<List<RequestWeatherModel>>(null, "找不到城市");
                var cityName = Pinyin.GetString(keyModel.keyName.EndsWith("市") ? keyModel.keyName.Substring(0, keyModel.keyName.Length - 1) : keyModel.keyName, PinyinFormat.WithoutTone).Replace(" ", "");
                string cityReplace = AreaCheckAndRetrun.AreaCheck4Retrun(keyModel);
                //Console.WriteLine(cityReplace);
                cityName = cityReplace;
                List<RequestWeatherModel> wLst = new List<RequestWeatherModel>();
                //前天
                {
                    RequestWeatherModel m = await this.GetDataFromOld(cityName, data.AddDays(-2));
                    wLst.Add(m);
                }
                //昨天
                {
                    RequestWeatherModel m = await this.GetDataFromOld(cityName, data.AddDays(-1));
                    wLst.Add(m);
                }
                //未来5天
                {
                    wLst.AddRange(await this.GetDataFromAsync(cityName, data));
                }

                lst[key] = wLst;
                return ResultApi.ok<List<RequestWeatherModel>>(wLst);
            }
            catch {
                return ResultApi.error<List<RequestWeatherModel>>(null);
            }
        }
        
        private async Task<RequestWeatherModel> GetDataFromOld(string cityName,DateTime date)
        {
            try
            {
                HttpClientHandler clientHandler = new HttpClientHandler();
                clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };


                string url = $"https://www.tianqishi.com/{cityName}/{date.AddDays(-2):yyyyMMdd}.html";
                HttpClient client = new HttpClient(clientHandler);
                var http = await client.GetAsync(url);
                var html = await http.Content.ReadAsStringAsync();
                Document doc = NSoupClient.Parse(html, "https://www.tianqishi.com");
                if (doc == null) throw new Exception("获取前天天数数据失败");
                var div = doc.GetElementsByClass("jdjianjie");
                if (div == null && div.Any() == false) throw new Exception("天数数据发生结构变化,请联系技术员修正");
                var p = div.First().GetElementsByTag("p");
                if (p == null || p.Count() < 2)
                {
                    throw new Exception("天数数据发生结构变化,请联系技术员修正");
                }
                var strs = p.ElementAt(1).Html().Split("，");
                RequestWeatherModel m = new RequestWeatherModel()
                {
                    date = date,
                    weather = strs.Where(x => x.Contains("天气：")).Select(x => x.Split("：").Last()).First(),
                    temperature = strs.Where(x => x.Contains("气温")).Select(x => x.Split("：").Last()).First(),
                    rainfall = strs.Where(x => x.Contains("降雨量：")).Select(x => x.Split("：").Last()).First(),
                    weatherImg = new List<string>()
                };
                return m;
            }
            catch (Exception e){
                return null;
            }
        }

        private async Task<List<RequestWeatherModel>> GetDataFromAsync(string cityName, DateTime date)
        {
            try
            {
                string url = $"https://www.tianqishi.com/{cityName}-7.html";
                HttpClientHandler clientHandler = new HttpClientHandler();
                clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
                HttpClient client = new HttpClient(clientHandler);
                var http = await client.GetAsync(url);
                var html = await http.Content.ReadAsStringAsync();

                Document doc = NSoupClient.Parse(html, "https://www.tianqishi.com");
                if (doc == null) throw new Exception("获取前天天数数据失败");
                var dl = doc.GetElementsByTag("dl");
                if (dl == null && dl.Any() == false) throw new Exception("天数数据发生结构变化,请联系技术员修正");
                List<RequestWeatherModel> lst = new List<RequestWeatherModel>();
                for (int i = 0; i < 5; i++)
                {
                    var dd = dl.ElementAt(i).GetElementsByTag("dd");
                    var li = dl.ElementAt(i).GetElementsByTag("li");
                    var img = dl.ElementAt(i).GetElementsByTag("img");

                    RequestWeatherModel m = new RequestWeatherModel()
                    {
                        date = date.AddDays(i),
                        weather = dd.ElementAt(3).Html(),
                        temperature = dd.ElementAt(4).Html(),
                        rainfall = li.Where(x => x.Html().Contains("降水量：")).Select(x => x.Html().Split("：").Last()).First(),
                        weatherImg = img.Select(x =>
                        {
                            HttpClient client = new HttpClient(clientHandler);
                            client.MaxResponseContentBufferSize = 256000;
                            Stream stream = client.GetStreamAsync("https://www.tianqishi.com/" + x.Attr("src")).Result;
                            byte[] bytes;
                            using (var memoryStream = new MemoryStream())
                            {
                                stream.CopyTo(memoryStream);
                                bytes = memoryStream.ToArray();
                            }
                            stream.Dispose();
                            return Convert.ToBase64String(bytes);
                        }).ToList()
                    };
                    lst.Add(m);
                }

                return lst;
            }
            catch (Exception ex) {
                return null;
            }
        }

    }
}
